﻿using System;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using Cms.Domain.Authentication;

namespace Cms.Web.Framework.Infrastructure
{
    public class SwfUploadAuthentication : IHttpModule
    {
        #region IHttpModule Members

        public void Dispose()
        {
        }
        
        public void Init(HttpApplication application)
        {
            application.BeginRequest += BeginRequest;
        }

        #endregion

        private void BeginRequest(object sender, EventArgs e)
        {
            var context = (HttpApplication)sender;
            /* Fix for the Flash Player Cookie bug in Non-IE browsers.
             * Since Flash Player always sends the IE cookies even in FireFox
             * we have to bypass the cookies by sending the values as part of the POST or GET
             * and overwrite the cookies with the passed in values.
             * 
             * The theory is that at this point (BeginRequest) the cookies have not been read by
             * the Session and Authentication logic and if we update the cookies here we'll get our
             * Session and Authentication restored correctly
             */

            if (context.Request.Path.ToLower().IndexOf("admin/processuploadedfile.aspx") == -1)
                return;

            try
            {
                string sessionParamName = "ASPSESSID";
                string sessionCookieName = "ASP.NET_SESSIONID";
                if (HttpContext.Current.Request.Form[sessionParamName] != null)
                    UpdateCookie(sessionCookieName, HttpContext.Current.Request.Form[sessionParamName]);
                else if (context.Request.QueryString[sessionParamName] != null)
                    UpdateCookie(sessionCookieName, HttpContext.Current.Request.QueryString[sessionParamName]);
            }
            catch (Exception)
            {
                context.Response.StatusCode = 500;
                context.Response.Write("Error Initializing Session");
            }

            try
            {
                string encryptedTicket = context.Request.Cookies[FormsAuthentication.FormsCookieName] != null
                                             ? context.Request.Cookies[FormsAuthentication.FormsCookieName].Value
                                             : HttpContext.Current.Request.Params[FormsAuthentication.FormsCookieName];
                if (HttpContext.Current.User == null && encryptedTicket != null)
                {
                    //FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);
                    FormsAuthenticationTicket ticket = FormsAuthentication.Decrypt(encryptedTicket);
                    if (ticket != null)
                    {
                        var identity = new FormsIdentity(ticket);
                        AuthenticatedUser user = Conversion.ToAuthenticatedUser(identity.Name);
                        if (user.AdministratorID > 0)
                        {
                            string[] roles = identity.Ticket.UserData.Split("|".ToCharArray());
                            var principal = new GenericPrincipal(identity, roles);
                            HttpContext.Current.User = principal;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                context.Response.StatusCode = 500;
                context.Response.Write("Error Initializing Forms Authentication: " + ex.Message + " " + ex.StackTrace);
            }
        }

        private void UpdateCookie(string cookieName, string cookieValue)
        {
            HttpCookie cookie = HttpContext.Current.Request.Cookies.Get(cookieName);
            if (cookie == null)
            {
                cookie = new HttpCookie(cookieName);
                HttpContext.Current.Request.Cookies.Add(cookie);
            }
            cookie.Value = cookieValue;
            HttpContext.Current.Request.Cookies.Set(cookie);
        }
    }
}